<?php

namespace App\Http\Requests;

use Illuminate\Database\Query\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class FollowUpStoreRequest extends FormRequest
{
    protected $drug;

    protected $weight;

    /**
     * Prepare the data for validation.
     * @return void
     */
    protected function prepareForValidation()
    {
        $this->drug   = app('field')->get('drug');
        $this->weight = app('field')->get('weight');
    }

    /**
     * Determine if the user is authorized to make this request.
     * @return bool
     */
    public function authorize()
    {
        return \Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     * @return array
     */
    public function rules()
    {
        return [
            'record_id'                       => [
                'required', 'integer', 'min:1',
                Rule::exists('st_medical_records', 'id')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                    $user = \Auth::user();
                    if (!$user->isDoctorsAdmin() && !$user->isAdmin()) {
                        $query->where(['doctor_id' => $user->id]);
                    }
                }),
            ],
            'blood_glucose'                   => 'nullable|array',
            'blood_glucose.limosis.low'       => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'blood_glucose.limosis.high'      => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'blood_glucose.postprandial.low'  => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'blood_glucose.postprandial.high' => 'nullable|numeric|min:0.1|max:50|decimal:1',

            'interval_evaluation.blood_glucose' => 'in:1,2',
            'interval_evaluation.weight.change' => 'in:0,1,2',
            'interval_evaluation.weight.effect' => [
                'required_if:interval_evaluation.weight.change,1,2',
                'import_unless_not:interval_evaluation.weight.change,0',
                Rule::in(array_keys($this->weight['status'])),
            ],
            'interval_evaluation.weight.kg'     => 'import_unless:interval_evaluation.weight.effect,1|numeric|min:0|max:999|decimal:1',
            'interval_evaluation.hypoglycemia'  => 'in:1,2,3',
            'interval_evaluation.remark'        => 'string|max:50',

            'interval_symptom.symptoms'   => [
                'array', 'max:5',
                Rule::exists('tn_dic_complain', 'name')->where(function (Builder $query) {
                    $query->where(['isdel' => 0]);
                }),
            ],
            'interval_symptom.symptoms.*' => 'string',

            'interval_symptom.remark' => 'string|max:50',

            'medication'                              => 'nullable|array',
            'medication.*.name'                       => [
                'required_with:medication.*',
                Rule::exists('st_drug_dictionary', 'name')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                }),
            ],
            'medication.*.dosage.type'                => 'in:' . implode(',', $this->drug['dosage'][2]['type']),
            'medication.*.dosage.value'               => 'numeric|min:0|max:999|decimal:2',
            'medication.*.dosage.values'              => 'array|min:1|max:4',
            'medication.*.dosage.values.morning'      => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.values.atnoon'       => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.values.evening'      => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.values.before_sleep' => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.unit'                => 'in:' . implode(',', $this->drug['dosage'][2]['unit']),
            'medication.*.start_time'                 => 'date',
            'medication.*.end_time'                   => 'date|after_or_equal:medication.*.start_time',
            'medication.*.usage'                      => 'in:' . implode(',', $this->drug['usage'][2]),
            'medication.*.frequency'                  => 'in:' . implode(',', $this->drug['frequency'][2]),
            'medication.*.remark'                     => 'string|max:50',

            'cn_medication.*.drugs.*.name'   => [
                'string',
                Rule::exists('st_drug_dictionary', 'name')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                }),
            ],
            'cn_medication.*.drugs.*.weight' => 'required|numeric|min:0|max:999',
            'cn_medication.*.usage'          => 'required|in:' . implode(',', $this->drug['usage'][1]),
            'cn_medication.*.dosage'         => 'required|in:' . implode(',', $this->drug['dosage'][1]['type']),
            'cn_medication.*.frequency'      => 'required|in:' . implode(',', $this->drug['frequency'][1]),
            'cn_medication.*.dose'           => 'required|integer|min:0|max:999',

            'diet'           => 'nullable|array',
            'diet.staple'    => 'numeric|min:0|max:999|decimal:1',
            'diet.meat'      => 'in:1,2,3',
            'diet.fat'       => 'in:1,2,3',
            'diet.vegetable' => 'in:1,2,3',
            'diet.fruit'     => 'in:1,2,3',
            'diet.salt'      => 'in:1,2,3',

            'sport' => 'in:0,1,2,3,4,5',

            'normal.diet'        => 'in:1,2,3',
            'normal.sleep'       => 'in:1,2,3',
            'normal.spirit'      => 'in:1,2,3',
            'normal.emotion'     => 'in:1,2,3',
            'normal.shit.value'     => 'in:1,2,3,4,5',
            'normal.shit.frequency' => 'in:1,2,3,4,5,6',
            'normal.shit.remark' => 'string|max:50',
            'normal.pee.value'   => 'in:0,1,2,3,4,5,6',
            'normal.pee.frequency'  => 'in:0,1,2,3,4,5,6',
            'normal.pee.remark'  => 'string|max:50',

            'remark' => 'nullable|string|max:255',
        ];
    }

    public function messages()
    {
        return [
            'record_id.required' => '缺少病历ID',
            'record_id.integer'  => '病历ID 必须是整数。',
            'record_id.min'      => '病历ID 必须大于等于 :min。',
            'record_id.exists'   => '病历 不存在或无修改该病历的权限。',

            'medication.*.dosage.value.required_if' => '每次剂量的剂量值 不能为空。',
            'medication.*.dosage.value.numeric'     => '剂量值 必须是一个数字。',
            'medication.*.dosage.value.decimal'     => '剂量值 只能保留一位小数。',
            'medication.*.dosage.value.min'         => '剂量值 必须大于等于 :min。',
            'medication.*.dosage.value.max'         => '剂量值 最大 :max。',

            'medication.*.dosage.values.*.required_if' => '分次剂量的剂量值 不能为空。',
            'medication.*.dosage.values.*.numeric'     => '剂量值 必须是一个数字。',
            'medication.*.dosage.values.*.decimal'     => '剂量值 只能保留一位小数。',
            'medication.*.dosage.values.*.min'         => '剂量值 必须大于等于 :min。',
            'medication.*.dosage.values.*.max'         => '剂量值 不能大于 :max。',

            'remark.max' => '备注最大 :max 个字符',
        ];
    }
}
